<?php
uses('sanitize');

class BillsController extends AppController {

	var $name = 'Bills';
	var $helpers = array('Html', 'Form', 'Ajax');
	var $components = array('Acl', 'Security', 'RequestHandler');
	
	function beforeFilter()
	{
		$this->Security->requirePost('customer_list', 'addProductToBill', 'incProduct', 'decProduct', 'delProduct');
		$this->Security->requireAuth('order');
		$this->Security->blackHoleCallback = 'invalid';
	}

	function invalid()
	{
		header ('HTTP/x 400 Bad Request');
		echo('<h1>Upward : erreur 400</h1>');
		echo('<p>Un probleme est servenue, merci de renvoyer le formulaire une nouvelle fois.</p>');
		die;
	}
	
//action customers
	function addToOrder(){
		$this->data['Bill']['type'] = 'order';
		$this->data['Bill']['customer_id'] = $this->Session->read('customer_id');
		
		if($this->Bill->save($this->data)) {
				$this->Session->setFlash('The Bill has been saved');
				
				$this->Bill->productExtra();
				$bill_id = $this->Bill->getLastInsertID();
				
				//add products to the bill
				$ar_products = $this->Session->read('basket');
				foreach($ar_products as $product){
					$product['product_id'] = $product['id'];
					$product['bill_id'] = $bill_id;
					$this->Bill->BillsProduct->save($product);
				}
				
				//Acl
				$bill_alias = 'bill-'.$bill_id;
				$aco = new Aco();
				$aco->create(0, 0, $bill_alias);
				$this->Acl->allow($this->Session->read('user'), $bill_alias, 'read');
				$this->Acl->allow('dealers', $bill_alias, '*');
				$this->Acl->deny('dealers', $bill_alias, 'delete');
				$this->Acl->allow('admins', $bill_alias, '*');
				
				$this->Session->delete('basket');
				$this->redirect('/bills/view/'.$bill_id);
			}		
	}

	function mybill(){
		if($this->Session->read('user')){
			$title = 'Mes factures';
			$this->pageTitle = $title;
			$this->set('actionTitle', $title);
		
			$this->Bill->recursive = 0;
			$customer_id = $this->Session->read('customer_id');
			$this->set('bills', $this->Bill->findAll(array('customer_id' => $customer_id, 'type' => 'bill'), null, 'Bill.modified DESC'));
			$this->render('index');
		}else{
			$this->Session->setFlash('Connexion requise');
			$this->redirect('/users/login');
		}
	}
	
	function myorder(){
		if($this->Session->read('user')){
			$title = 'Mes commandes';
			$this->pageTitle = $title;
			$this->set('actionTitle', $title);
		
			$this->Bill->recursive = 0;
			$customer_id = $this->Session->read('customer_id');
			$this->set('bills', $this->Bill->findAll(array('customer_id' => $customer_id, 'type' => 'order')));
			$this->render('index');
		}else{
			$this->Session->setFlash('Connexion requise');
			$this->redirect('/users/login');
		}
	}

//action dealers
	function index() {
		if($this->Acl->check($this->Session->read('user'), '/bills', 'read')){
			$title = 'Liste des commandes et factures';
			$this->pageTitle = $title;
			$this->set('actionTitle', $title);
		
			$this->Bill->recursive = 0;
			$this->set('bills', $this->Bill->findAll(null, null, 'Bill.modified DESC'));
		}else{
			$this->Session->setFlash('Action non autorisée');
			$this->redirect('/');
		}
	}
	
	function bill(){
		if($this->Acl->check($this->Session->read('user'), '/bills', 'read')){
			$title = 'Liste des factures';
			$this->pageTitle = $title;
			$this->set('actionTitle', $title);
		
			$this->Bill->recursive = 0;
			$this->set('bills', $this->Bill->findAll(array('type' => 'bill'), null, 'Bill.modified DESC'));
			$this->render('index');
		}else{
			$this->Session->setFlash('Action non autorisée');
			$this->redirect('/');
		}
	}
	
	function order(){
		if($this->Acl->check($this->Session->read('user'), '/bills', 'read')){
			$title = 'Liste des commandes';
			$this->pageTitle = $title;
			$this->set('actionTitle', $title);
		
			$this->Bill->recursive = 0;
			$this->set('bills', $this->Bill->findAll(array('type' => 'order'), null, 'Bill.modified DESC'));
			$this->render('index');
		}else{
			$this->Session->setFlash('Action non autorisée');
			$this->redirect('/');
		}
	}

	function view($id = null) {
		if(!$id) {
			$this->Session->setFlash('Invalid id for Bill.');
			$this->redirect('/bills/index');
		}
		if($this->Acl->check($this->Session->read('user'), 'bill-'.$id, 'read')){
			$this->Bill->recursive = 2;
			$this->Bill->productExtra();
			$bill = $this->Bill->read(null, $id);
		
			$bill['Bill']['price']=$i=$j=0;
			foreach($bill['Product'] as $product){
				foreach($bill['BillsProduct'] as $billsproduct){
					if($bill['Product'][$i]['id'] == $bill['BillsProduct'][$j]['product_id']){
						$bill['Product'][$i]['quantity'] = $bill['BillsProduct'][$j]['quantity'];
						$bill['Product'][$i]['price_sell'] = $bill['BillsProduct'][$j]['price_sell'];
						$bill['Bill']['price'] += $bill['Product'][$i]['price_sell'] * $bill['Product'][$i]['quantity'];
					}
					$j++;
				}
				$i++;
				$j=0;
			}
			$this->set('bill', $bill);
		}
	}

	//ajax - call in view customers/ajaxadd.thtml POST
	//need @ /bills/add
	function customer_list(){
		$this->set('customers', $this->Bill->Customer->generateList(null, 'username ASC', null, '{n}.Customer.id', '{n}.Customer.username'));
		$this->render('customer_list','ajax');
	}
	
	
	//ajax - view product list at "recalculer" ajax-link
	function products_list(){
		$this->render('products_list', 'ajax');
	}
	
	//ajax - add a product to the bill in a session var require POST
	function addProductToBill(){
		$product_present = false;
		//if edited bill
		if($this->Session->read('bill_products')){
			$ar_products =  $this->Session->read('bill_products');
		
			//if product is already present in the bill_products session var add only quantity
			foreach($ar_products as $product_key => $ar_product){
				if($ar_product['id'] == $this->data['Product']['Product']){
					$key = $product_key;
					$product_present = true;
					break;
				}
			}
		}
		
		if($product_present){
			$ar_products[$product_key]['quantity'] = $ar_products[$key]['quantity']+$this->data['Product']['Quantity'];
		}else{
			//show product only
			$product = $this->Bill->Product->viewUnbindProduct($this->data['Product']['Product']);
		
			$product['Product']['quantity'] = $this->data['Product']['Quantity'];
			$ar_products[] = $product['Product'];
		}
	
		$this->Session->write('bill_products', $ar_products);	
		$this->render('products_list', 'ajax');
	}
	
	//ajax - increment quantity of a product require POST
	function incProduct($id){
		$ar_products =  $this->Session->read('bill_products');
		//find product in the bill_products session var
		foreach($ar_products as $product_key => $ar_product){
			if($ar_product['id'] == $id){
				$key = $product_key;
				break;
			}
		}
		if(isset($key)){
			$ar_products[$key]['quantity']++;
		}else{
			die('erreur');
		}
		$this->Session->write('bill_products', $ar_products);
		$this->render('products_list', 'ajax');
	}
	
	//ajax - decrement quantity of a product require POST
	function decProduct($id){
		$ar_products =  $this->Session->read('bill_products');
		//find product in the bill_products session var
		foreach($ar_products as $product_key => $ar_product){
			if($ar_product['id'] == $id){
				$key = $product_key;
				break;
			}
		}
		if(isset($key)){
			$ar_products[$key]['quantity']--;
			if($ar_products[$key]['quantity'] <= 0){
				unset($ar_products[$key]);
			}
		}else{
			die('erreur');
		}
		$this->Session->write('bill_products', $ar_products);
		$this->render('products_list', 'ajax');
	}
	
	//ajax - delete a product from bill session var require POST
	function delProduct($id){
		$ar_products =  $this->Session->read('bill_products');
		//find product in the bill_products session var
		foreach($ar_products as $product_key => $ar_product){
			if($ar_product['id'] == $id){
				$key = $product_key;
				break;
			}
		}
		if(isset($key)){
			unset($ar_products[$key]);
		}else{
			die('erreur');
		}
		$this->Session->write('bill_products', $ar_products);
		$this->render('products_list', 'ajax');
	}
	
	//ajax: modify price per unit
	function updatePrice(){
		$ar_products =  $this->Session->read('bill_products');
		//find product in the bill_products session var
		foreach($ar_products as $product_key => $ar_product){
			if($ar_product['id'] == $_POST['id']){
				$key = $product_key;
				break;
			}
		}
		if(isset($key)){
			$this->data['Product']['price_sell'] = $_POST['value'];
			if($this->Bill->Product->validates($this->data)){
				$ar_products[$key]['price_sell'] = $this->data['Product']['price_sell'];
			}else{
				$this->data['Product']['price_sell'] = $ar_products[$key]['price_sell'];
			}
		}else{
			die('erreur');
		}
		$this->Session->write('bill_products', $ar_products);
		$this->set('price', $this->data['Product']['price_sell']);
		$this->render('price', 'ajax');
	}
	
	function add() {
		if($this->Acl->check($this->Session->read('user'), '/bills', 'create')){
			if(empty($this->data)) {
				$this->Session->delete('bill_products');
				$this->set('products', $this->Bill->Product->generateList());
				$this->set('selectedProducts', null);
				$this->set('customers', $this->Bill->Customer->generateList(null, 'username ASC', null, '{n}.Customer.id', '{n}.Customer.username'));
				$this->render();
			} else {
				$this->cleanUpFields();
			
				if($this->Bill->save($this->data)) {
					$this->Session->setFlash('The Bill has been saved');
				
					$this->Bill->productExtra();
					if(empty($this->data['Bill']['id'])){
						$bill_id = $this->Bill->getLastInsertID();
					}else{
						$bill_id = $this->data['Bill']['id'];
					}
					//delete all products with bill_id from db habtm (for edit form)
					$this->Bill->BillsProduct->query('DELETE FROM `bills_products` WHERE `bill_id` ='.$bill_id);
					//add products to the bill
					$ar_products = $this->Session->read('bill_products');
					foreach($ar_products as $product){
						$product['product_id'] = $product['id'];
						$product['bill_id'] = $bill_id;
						//$this->Bill->BillsProduct->save($product);
						$this->Bill->BillsProduct->query('INSERT INTO `bills_products` (`price_sell`,`quantity`,`product_id`,`bill_id`) VALUES ('.$product['price_sell'].','.$product['quantity'].','.$product['product_id'].','.$product['bill_id'].')');
					}
					//ACL
						//bill acl exists?
					if(!$this->Acl->check($this->Session->read('user'), 'bill-'.$bill_id, 'update')){
						$aco = new Aco();
						$aco->create(0, 0 , 'bill-'.$bill_id);
						$this->Acl->allow('dealers', 'bill-'.$bill_id, '*');
						$this->Acl->deny('dealers', 'bill-'.$bill_id, 'delete');
						$this->Acl->allow('admins', 'bill-'.$bill_id, '*');
					}
					
					$this->Session->delete('bill_products');
					$this->redirect('/bills/view/'.$bill_id);
				} else {
					$this->Session->setFlash('Please correct errors below.');
					$this->set('products', $this->Bill->Product->generateList());
					if(empty($this->data['Product']['Product'])) { 
						$this->data['Product']['Product'] = null; 
					}
					$this->set('selectedProducts', $this->data['Product']['Product']);
					$this->set('customers', $this->Bill->Customer->generateList(null, 'username ASC', null, '{n}.Customer.id', '{n}.Customer.username'));
				}
			}
		}else{
			$this->Session->setFlash('Action non autorisée');
			$this->redirect('/');
		}
	}

	function edit($id = null) {
		$this->Session->delete('bill_products');
		if(empty($this->data)) {
			if(!$id) {
				$this->Session->setFlash('Invalid id for Bill');
				$this->redirect('/bills/index');
			}
			if($this->Acl->check($this->Session->read('user'), 'bill-'.$id, 'update')){
				$this->Bill->productExtra();
				$bill = $this->Bill->read(null, $id);
			
				$bill['Bill']['price']=$i=$j=0;
				foreach($bill['Product'] as $product){
					foreach($bill['BillsProduct'] as $billsproduct){
						if($bill['Product'][$i]['id'] == $bill['BillsProduct'][$j]['product_id']){
							$bill['Product'][$i]['quantity'] = $bill['BillsProduct'][$j]['quantity'];
							$bill['Product'][$i]['price_sell'] = $bill['BillsProduct'][$j]['price_sell'];
							$bill['Bill']['price'] += $bill['Product'][$i]['price_sell'] * $bill['Product'][$i]['quantity'];
						}
						$j++;
					}
					$i++;
					$j=0;
				}
	
				$this->Session->write('bill_products', $bill['Product']);
				$this->data = $bill;
				$this->set('products', $this->Bill->Product->generateList());
				if(empty($this->data['Product'])) { 
					$this->data['Product'] = null;
				}
				$this->set('selectedProducts', $this->_selectedArray($this->data['BillsProduct'], 'product_id'));
				$this->set('customers', $this->Bill->Customer->generateList(null, 'username ASC', null, '{n}.Customer.id', '{n}.Customer.username'));
			
				$this->render('add');
			}else{
				$this->Session->setFlash('Action non autorisée');
				$this->redirect('/');
			}
		} else {
			$this->Session->setFlash('erreur');
			$this->redirect('/bills');
		}
	}

	function setBill($id = null){
		if(!$id) {
			$this->Session->setFlash('Invalid id for Bill');
			$this->redirect('/bills/index');
		}else{	
			if($this->Acl->check($this->Session->read('user'), 'bill-'.$id, 'update')){	
				$error = false;
					//1 - find products with stock
				$this->Bill->recursive = 1;
				$ar_products = $this->Bill->read(null, $id);
				$ar_products = $ar_products['Product'];
				
					//2 - find billsproducts with quantity
				$this->Bill->productExtra();
				$ar_billsproduct = $this->Bill->BillsProduct->findAll(array('bill_id' => $id));
				
					//3 - foreach prod : stock - quantity
				$i = 0;
				$flashmsg = 'La commande est passée en facture,<br />';
				foreach($ar_products as $product){
					foreach($ar_billsproduct as $billsproduct){
						if($product['id'] == $billsproduct['BillsProduct']['product_id']){
							$this->data['Product'][$i]['id'] = $product['id'];
							$this->data['Product'][$i]['title'] = $product['title'];
							$this->data['Product'][$i]['stock'] = $product['stock']-$billsproduct['BillsProduct']['quantity'];
							$flashmsg .= 'il reste '.$this->data['Product'][$i]['stock'].' '.$product['title'].' en stock<br />';
						
							//3.1 - if stock neg : abort operation
							if($this->data['Product'][$i]['stock'] < 0){
								$this->Session->setFlash('Impossible de passer cette commande en facture <br />Stock negatif : '.$this->data['Product'][$i]['stock'].'<br />'.$product['title']);
								$this->redirect('/bills/view/'.$id);
								$error = true;
							}
							$i++;
						
						}
					}
				}
		
					//4 - foreach prod : update stock
				if(!$error){
					foreach($this->data['Product'] as $data_product['Product']){
						$this->Bill->Product->save($data_product);
					}
						//4.1 update bill
					$this->data['Bill']['type'] = 'bill';
					if($this->Bill->save($this->data)){
						$this->Session->setFlash($flashmsg);
						$this->redirect('/bills/view/'.$id);
					}else{
					$this->Session->setFlash('erreur à la sauvegarde');
					}
				}
			}else{
				$this->Session->setFlash('Action non autorisée');
				$this->redirect('/');
			}
		}
	}

	function setOrder($id = null){
		if(!$id) {
			$this->Session->setFlash('Invalid id for Bill');
			$this->redirect('/bills/index');
		}else{
			if($this->Acl->check($this->Session->read('user'), 'bill-'.$id, 'update')){
					//1 - find products with stock
				$this->Bill->recursive = 1;
				$ar_products = $this->Bill->read(null, $id);
				$ar_products = $ar_products['Product'];
					//2 - find billsproducts with quantity
				$this->Bill->productExtra();
				$ar_billsproduct = $this->Bill->BillsProduct->findAll(array('bill_id' => $id));
					//3 - foreach prod : stock + quantity
				$i = 0;
				$flashmsg = 'La facture est passée en commande,<br />';
				foreach($ar_products as $product){
					foreach($ar_billsproduct as $billsproduct){
						if($product['id'] == $billsproduct['BillsProduct']['product_id']){
							$this->data['Product'][$i]['id'] = $product['id'];
							$this->data['Product'][$i]['title'] = $product['title'];
							$this->data['Product'][$i]['stock'] = $product['stock']+$billsproduct['BillsProduct']['quantity'];
							$flashmsg .= 'il reste '.$this->data['Product'][$i]['stock'].' '.$product['title'].' en stock<br />';
							$i++;
						}
					}
				}
			
					//4 - foreach prod : update stock
				foreach($this->data['Product'] as $data_product['Product']){
					$this->Bill->Product->save($data_product);
				}
					//4.1 update bill
				$this->data['Bill']['type'] = 'order';
				if($this->Bill->save($this->data)){
					$this->Session->setFlash($flashmsg);
					$this->redirect('/bills/view/'.$id);
				}else{
					$this->Session->setFlash('Erreur lors de la sauvegarde');
				}
			}else{
				$this->Session->setFlash('Action non autorisée');
				$this->redirect('/');
			}
		}
	}
	
//action admin
	function delete($id = null) {
		if(!$id) {
			$this->Session->setFlash('Invalid id for Bill');
			$this->redirect('/bills/index');
		}
		if($this->Acl->check($this->Session->read('user'), 'bill-'.$id, 'delete')){
			if($this->Bill->del($id)) {
				//ACL
				$aco = new Aco();
				$aco->delete('bill-'.$id);
				
				$this->Session->setFlash('The Bill deleted: id '.$id.'');
				$this->redirect('/bills/index');
			}
		}else{
			$this->Session->setFlash('Action non autorisée');
			$this->redirect('/');
		}
	}

}
?>